<template>
  <div>
    <el-dialog :title="`${showTitle}部门`" :visible="showDialog" @close="closeDialog">
      <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px">
        <el-form-item label="部门名称" prop="name">
          <el-input v-model="formData.name" style="width: 80%;" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门编码" prop="code">
          <el-input v-model="formData.code" style="width: 80%;" placeholder="1-50个字符" />
        </el-form-item>
        <el-form-item label="部门负责人" prop="manager">
          <el-select
            v-model="formData.manager"
            style="width: 80%;"
            value=""
            placeholder="请选择"
            @focus="fetchGetEmployeeSimple"
          >
            <el-option v-for="item in peoples" :key="item.id" :value="item.username" :label="item.username" />
          </el-select>
        </el-form-item>
        <el-form-item label="部门介绍" prop="introduce">
          <el-input v-model="formData.introduce" style="width: 80%;" type="textarea" placeholder="1-300个字符" />
        </el-form-item>
      </el-form>

      <template #footer>
        <el-row type="flex" justify="center">
          <el-col :span="8">
            <el-row type="flex" justify="space-around">
              <el-button size="mini" type="primary" @click="submitDeparts">确定</el-button>
              <el-button size="mini" @click="closeDialog">取消</el-button>
            </el-row>
          </el-col>
        </el-row>
      </template>
    </el-dialog>
  </div>
</template>

<script>
// 需求：只有一级部门展示添加按钮
// 二级部门只有删除和编辑功能

// tree-tool组件点击新增的时候，触发父组件的自定义事件
// 自定义事件内部：控制弹层标识变为true，同时记录当前点击的节点数据对象
// 弹层标识传递给弹层组件，就可以让弹层做展示

// 1、控制弹层的标识如果添加.sync去控制行不行？

// 分析问题：
// 1、.sync修饰符作用
//    允许子组件直接修改父组件数据

import { addDepartments, getDepartDetail, getDepartments, updateDepartments } from '@/api/departments'
import { getEmployeeSimple } from '@/api/employees'

export default {
  name: 'AddDept',
  props: {
    showDialog: {
      type: Boolean,
      default: false
    },
    treeNode: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    // 判断部门编码的逻辑
    // 底层规则：所有的code都不能重复
    // 同级的name不能重复
    const checkName = async(rules, value, callback) => {
      // 需求：区分新增和编辑的场景？
      // 理解需求：新增和编辑的区别？
      // --> 新增部门：当前新增的部门会成为点击部门的子部门(跟自己的子部门对比是否重复)
      // --> 编辑部门：编辑成功提交的时候，编辑的部门就是自己(查重复的时候，自己的同级比较是否重复)

      // 添加部门
      // 新添加的部门的name值不能和我当前点击的部门的子部门的name重复
      // 获取所有的部门数据，然后做筛选
      const { depts } = await getDepartments()
      // 找到当前点击的部门的子部门

      // 区分currentChild：新增：找到当前点击部门的所有子部门
      //  编辑：找当前点击部门的同级部门
      let currentChild
      if (this.formData.id) {
        //  编辑
        // 同级部门有什么特点？pid相同
        currentChild = depts.filter(item => item.pid === this.treeNode.pid && item.id !== this.treeNode.id)
      } else {
        //  新增
        currentChild = depts.filter(item => item.pid === this.treeNode.id)
      }
      // 新添加的部门的name值 不能 和我当前点击的部门的子部门的name重复
      const isRepeat = currentChild.some(item => item.name === value)

      callback(isRepeat ? new Error(`同级部门中已经有了${value}部门，请更换其他部门名称`) : undefined)
    }
    // code的校验规则
    const checkCode = async(rules, value, callback) => {
      // 1、获取到所有的部门数据
      const { depts } = await getDepartments()
      // 2、直接判断当前新增的code是否根原有的code有重复的
      let isRepeat
      if (this.formData.id) {
        // 编辑
        // some方法只要有一个满足条件就返回true
        // isRepeat如果为true表示重复
        // 如果some方法返回了true表示重复了
        // 1001
        // 只有满足两个条件才是重复的
        // 1、编辑的部门编码在原有部门数据里面找到了 && 满足第一个条件的部门不能是我点击的部门
        // some只要有一个满足条件直接返回true
        // &&必须前后同时满足条件才返回true
        isRepeat = depts.some(item => item.code === value && item.id !== this.treeNode.id)
      } else {
        //  新增
        isRepeat = depts.some(item => item.code === value)
      }
      callback(isRepeat ? new Error(`同级部门中已经有了${value}编码，请更换其他部门编码`) : undefined)
    }
    return {
      peoples: [],
      formData: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: 'blur' },
          {
            validator: checkName,
            trigger: 'blur'
          }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: 'blur' },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: 'blur' },
          {
            validator: checkCode,
            trigger: 'blur'
          }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: 'blur' }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: 'blur' },
          { trigger: 'blur', min: 1, max: 300, message: '部门介绍要求1-300个字符' }
        ]
      }
    }
  },
  computed: {
    showTitle() {
      return this.formData.id ? '编辑' : '新增'
    }
  },
  methods: {
    closeDialog() {
      this.$emit('update:showDialog', false)
      // 重置表单的校验和表单内部的数据
      this.$refs.formRef.resetFields()
      // 重置数据
      this.formData = {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      }
    },
    async getDepartDetail(id) {
      // 通过id获取部门详情数据
      // 把获取到的部门详情数据赋值给formData -> 让数据做回显
      this.formData = await getDepartDetail(id)
    },
    async submitDeparts() {
      // 提交之前需要判断新增还是编辑
      // 点击确定按钮去提交的时候
      // 1、表单校验(校验通过之后再去提交)
      await this.$refs.formRef.validate()
      // 2、提交数据（服务器的数据会更新）==> 重新调用接口，拿到最新的数据
      if (this.formData.id) {
        // 编辑更新
        await updateDepartments(this.formData)
      } else {
        //  新增部门
        await addDepartments({
          ...this.formData,
          pid: this.treeNode.id
        })
      }

      // 进行成功提示
      this.$message.success(`${this.showTitle}成功`)
      // 重新获取列表数据
      this.$emit('getDepts')
      //  关闭弹层
      this.closeDialog()
    },
    //  获取部门列表数据
    async fetchGetEmployeeSimple() {
      this.peoples = await getEmployeeSimple()
    }
  }
}
</script>
